#include "../../include/Reactor/SearchEngineServer.h"
#include "../../include/Reactor/MyTask.h"
#include "../../include/Reactor/TLV.h"
#include "../../include/Reactor/ProtocolParser.h"
#include "../../include/Reactor/MyThread.h"

using ElemType = function<void(MyThread*)>;
SearchEngineServer::SearchEngineServer(size_t threadNum, size_t queSize, const string & ip, unsigned short port) 
: _pool(threadNum,queSize)
, _server(ip,port)
{

}

SearchEngineServer::~SearchEngineServer() {

}

void SearchEngineServer::start() {
    _pool.start();

    using namespace std::placeholders;
    _server.setAllCallback(
                           bind(&SearchEngineServer::onNewConnection,this,_1),
                           bind(&SearchEngineServer::onMessage,this,_1),
                           bind(&SearchEngineServer::onClose,this,_1),
                           bind(&SearchEngineServer::setTimeCallback,this,&_pool)
                          );

    _server.start();
}

void SearchEngineServer::stop() {
    _pool.stop();
    _server.stop();
}

void SearchEngineServer::onNewConnection(const TcpConnectionPtr & con) {
    cout << con->toString() << " 已连接!!! " << endl;
}

void SearchEngineServer::onMessage(const TcpConnectionPtr & con) {
    // 从receive中得到数据
    string data = con->receive();
#ifdef DEBUG
    cout << "接收到数据" << endl;
#endif

    if(data.empty())
    {
        std::cerr << "接收消息失败!" << endl;
        return;
    }

    // 反序列化
    Message msg = ProtocolParser::parseMessage(data);
#ifdef DEBUG
    cout << "正在反序列化..." << endl;
#endif


#ifdef DEBUG
    cout << "任务类型：[";
    if(msg.tag == KeyRecommand)
    {
        cout << "关键字查询";
    }else if(msg.tag == WebPageSearch)
    {
        cout << "网页搜索";
    }else
    {
        cout << "错误请求";
    }
    cout << "]" << endl << "请求参数：[" << msg.value << "]" << endl;
#endif

    // 创建任务
    MyTaskPtr task = ProtocolParser::makeTask(msg, con);
#ifdef DEBUG
    cout << "正在创建任务..." << endl;
#endif

#ifdef DEBUG
    cout << "创建任务成功" << endl;
#endif

    _pool.addTask([task](MyThread *myTh)
    {
        task->process(myTh);
    });
}

void SearchEngineServer::onClose(const TcpConnectionPtr & con) {
    cout << con->toString() << " 断开连接!!! " << endl;
}


void SearchEngineServer::setTimeCallback(ThreadPool *pool)
{
    cout << "开始复制缓存" << endl;
    for(auto &th : pool->m_threads)
    {
        auto v1 = th->patch.getAll();
        if(!v1.empty()){
            for(auto &temp : v1)
            {
                pool->m_cache.put(temp.first, temp.second);
            }
        }
        auto v2 = pool->m_cache.getAll();
        if(!v2.empty()){
            for(auto &temp : pool->m_cache.getAll())
            {
                th->cache.put(temp.first, temp.second);
            }
        }
    }
    cout << "复制完成" << endl;
}